#!/usr/bin/env python
# encoding: utf-8
# @author: Lin Han
# @contact: voldemort22@126.com
# @file: deprecated_app.py
# @time: 2021/3/23 18:48
# @desc:
import json

import requests
from fastapi import APIRouter, File, UploadFile, Request, BackgroundTasks

from application.parameter_model.crud import generate_parameter_model_data
from application.parameter_model.queryModels import ParameterModelChangeSize, UploadParameterModel
from background.background_update import update_05
from cache.redis_pool import get_redis
from models.queryModels import UpdateParamConfigData, MultipleConditionQueryParameterModels, LockFlagQuery, UpdateParamModelProperty
from models.responseModels import ResponseBool, ResponseDict, ResponseStr
from utils.mongo_tools import retrieve_all_mongo_values, update_mongo_value, delete_mongo_value, create_one_mongo_value, retrieve_one_mongo_value, parameter_model_number_generator
from utils.utils import create_folder, write_file
from views.configs import *
from views.crud import upload_to_aliyun_parameter_model, keyword_search_parameter, separate_page, send_to_message_queue

parameter_model_router = APIRouter(
    prefix="/api/parameter_model",
    tags=["parameter_model"],
)


@parameter_model_router.post("/v1/parameter_models")
def multiple_condition_query_parameter_models(queryModel: MultipleConditionQueryParameterModels, background_tasks: BackgroundTasks):
    """
    获取 所有符合条件的 参数化模型的数据
    如果redis里用202105开头的正则匹配不到一条数据，那就去mongo数据库里取所有的参数化模型数据，把它们存到redis里。

    - :param queryModel:
    - :return:
    """
    redis_connection = get_redis(port=PARAMETER_MODEL_REDIS_PORT)
    model = {"data": {"result": []}}
    try:
        parameter_model_number_list = redis_connection.get("parameter_model")
        parameter_model_number_list = json.loads(parameter_model_number_list)
        parameter_model = redis_connection.mget(*parameter_model_number_list)
        result = [json.loads(i) for i in parameter_model]
    except:
        result = retrieve_all_mongo_values(
            {},
            collection_name=PARAMETER_MODEL_COLLECTION
        )
        background_tasks.add_task(update_05)

    result = keyword_search_parameter(queryModel, result)
    model["data"]["total"] = len(result)
    if len(result) > 0:
        # 如果isTotal为True，意味着进入了详情页面，则不需要分页了。
        if not queryModel.isTotal:
            model["data"]["result"] = separate_page(result, page=queryModel.page, pagesize=queryModel.pagesize)
        else:
            model["data"]["result"] = result
    model["status"] = 1
    return model


@parameter_model_router.put("/v1/parameter_model_flag_tag")
def update_parameter_model_flag_tag(queryModel: LockFlagQuery, background_tasks: BackgroundTasks):
    """
    设置 参数化模型 标签锁定 isFlag = True

    - :param oneInfo:
    - :return:
    """
    updateInfo = {"$set": {"isFlag": queryModel.isFlag}}
    update_mongo_value(
        {"number": queryModel.number},
        updateInfo,
        collection_name=PARAMETER_MODEL_COLLECTION
    )
    background_tasks.add_task(update_05)
    model = {"data": True, "status": 1}
    return model


@parameter_model_router.delete("/v1/parameter_model")
def delete_parameter_model(number: str, background_tasks: BackgroundTasks):
    """
    删除 一个 参数化模型 字段
    - :param number:
    - :return:
    """
    delete_mongo_value(
        number=number,
        database_name=MONGO_DATABASE_NAME,
        collection_name=PARAMETER_MODEL_COLLECTION
    )

    background_tasks.add_task(update_05)
    model = {"data": True, "status": 1}
    return model


@parameter_model_router.put("/v1/parameter_model", response_model=ResponseBool)
def update_parameter_model(queryModel: UpdateParamModelProperty, background_tasks: BackgroundTasks):
    """
    参数化模型 详情页更新

    - :param queryModel:
    - :return:
    """
    tag = retrieve_all_mongo_values(
        {"number": queryModel.number},
        collection_name=PARAMETER_MODEL_COLLECTION,
    )[0]['tag']
    if queryModel.standard is not None:
        tag['standard'] = queryModel.standard
    if queryModel.category is not None:
        tag['category'] = queryModel.category
    if queryModel.partType is not None:
        tag['partType'] = queryModel.partType
    if queryModel.elseTag is not None:
        tag['elseTag'] = queryModel.elseTag
    updateInfo = {"$set": {"tag": tag}}
    update_mongo_value(
        {"number": queryModel.number},
        updateInfo,
        collection_name=PARAMETER_MODEL_COLLECTION
    )
    background_tasks.add_task(update_05)
    model = {"data": True, "status": 1}
    return model


@parameter_model_router.get("/v1/parameter_model")
def retrieve_history_part(number: str, background_tasks: BackgroundTasks):
    """
    返回一条参数化模型的完整信息

    - :param number: 编号
    - :return:
    """
    redis_connection = get_redis(port=PARAMETER_MODEL_REDIS_PORT)
    try:
        parameter_model = redis_connection.get(number)
        original_data = json.loads(parameter_model)
    except:
        original_data = retrieve_one_mongo_value(number, collection_name=PARAMETER_MODEL_COLLECTION)[0]
        background_tasks.add_task(update_05)

    model = {"data": {}}
    try:
        model["data"] = original_data
        model["status"] = 1
    except:
        model["status"] = 0
    return model


@parameter_model_router.put("/v1/parameter_model_config", response_model=ResponseBool)
def update_parameter_model_config(oneInfo: UpdateParamConfigData):
    """
    这个是更新config表的，不是更新数据表格，别和parameter_model的url混了。

    - :param oneInfo:
    - :return:
    """
    redis_connection = get_redis(port=PARAMETER_MODEL_REDIS_PORT)
    configData = retrieve_all_mongo_values(
        {"type": CONFIG_DATA_PARAMETER_MODEL_TYPE},
        collection_name=CONFIG_COLLECTION,
    )[0][CONFIG_DATA]
    if oneInfo.standard is not None:
        configData['standard'] = oneInfo.standard
    if oneInfo.makeType is not None:
        configData['makeType'] = oneInfo.makeType
    if oneInfo.version is not None:
        configData['version'] = oneInfo.version
    if oneInfo.partType is not None:
        configData['partType'] = oneInfo.partType
    updateInfo = {"$set": {"configData": configData}}
    update_mongo_value(
        {"type": CONFIG_DATA_PARAMETER_MODEL_TYPE},
        updateInfo,
        collection_name=CONFIG_COLLECTION,
    )

    redis_connection.set("parameter_model_config", json.dumps(configData))

    model = {"data": True, "status": 1}
    return model


@parameter_model_router.get("/v1/parameter_model_config", response_model=ResponseDict)
def get_parameter_model_values():
    """
    获取 参数化模型 所需要的配置信息
    - :return:
    """
    redis_connection = get_redis(port=PARAMETER_MODEL_REDIS_PORT)
    try:
        configData = redis_connection.get("parameter_model_config")
        configData = json.loads(configData)
    except:
        configData = retrieve_all_mongo_values(
            {"type": CONFIG_DATA_PARAMETER_MODEL_TYPE},
            collection_name=CONFIG_COLLECTION,
        )[0]['configData']
        # 把mongo中查到的数据set到redis数据库中
        redis_connection.set("parameter_model_config", json.dumps(configData))

    model = {"data": configData, "status": 1}

    return model


@parameter_model_router.get("/v1/parameter_model_gltf_file", response_model=ResponseStr)
async def get_parameter_model_gltf_file(number: str):
    """
    Deprecated.
    查询 参数化模型的gltf文件地址，用于显示

    - :param number:
    - :return:
    """
    model = {"data": ""}
    original_data = retrieve_one_mongo_value(
        number,
        database_name=MONGO_DATABASE_NAME,
        collection_name=PARAMETER_MODEL_COLLECTION,
    )
    try:
        model["data"] = original_data[0]["file"][GLTF_OSS_ADDRESS]
        model["status"] = 1
    except:
        model["status"] = 0
    return model


@parameter_model_router.put("/v1/parameter_model_show")
def change_size(queryModel: ParameterModelChangeSize):
    """
    关联中实时更改模型尺寸。首先会删除queryModel.number对应的原来的临时stl模型（如果有的话，这个模型是来自于之前对同一number的模型进行的操作而存在同一文件夹下），以免用户点击更新后看到错误尺寸的stl

    - :param queryModel:
    - :return:
    """
    # temp_stl_oss_address = f"DOCenter_Dev/Pythonfiles/temp/parameter_model/{queryModel.number}.glb"
    # print(delete_file_on_oss(temp_stl_oss_address))
    result = retrieve_all_mongo_values(
        filter_conditions={"number": queryModel.number},
        collection_name=PARAMETER_MODEL_COLLECTION,
    )[0]

    result["file"]["tempArgs"] = [i.dict() for i in queryModel.args]

    # 发送去转化服务器的数据中，"file"里"tempArgs"的字段是这次添加的数据，且也已转化为字典了。
    data = requests.request(
        method="post",
        url=f"http://{TEMPORARY_CONVERT_MACHINE_URL}:{TEMPORARY_CONVERT_MACHINE_PORT}/parameter_model",
        # data=str(result, encoding="utf-8").encode('utf-8'),
        data=json.dumps(result)
    )

    model = {"data": data, "status": 1}
    return model
